#include "../../include/Particle.hpp"
#include "../../include/Utils.hpp"
using namespace klas;

#include <iostream>
using namespace std;

Particle::Particle()
{
  m_life = 0.0;
  m_currentScale = 1.0;
  m_targetScale = 1.0;
  m_tex = NULL;
}

Particle::~Particle()
{
}

void Particle::recreate(Real lifespan, Real initialScale, Real finalScale,
                        const Vector2<Real>& velocity, const Vector2<Real>& pos, 
                        const Color& initialCol, const Color& finalCol, 
                        Texture* tex)
{
  m_life = lifespan;
  m_currentScale = initialScale;
  m_targetScale = finalScale;
  m_velocity = velocity;
  m_pos = pos;
  m_currentCol = initialCol;
  m_targetCol = finalCol;
  m_tex = tex;
  
}

Real getNewColor(Real dt, Real start, Real target)
{
  if(Utils::isEqual(start, target))
    return target;

  Real modedTarget = target;
  if(Utils::isEqual(modedTarget, 0))
    modedTarget = 1;

  // If we don't have nested ifs checking for overshoot, then we will just
  // continously pulsate between start and target.
  if(start < target)
  {
    start += modedTarget * dt;
    if(start > target)
      start = target;
  }

  if(start > target)
  {
    start -= modedTarget * dt;
    if(start < target)
      start = target;
  }
  return start;
}

void changeColors(Real dt, Color& start, const Color& target)
{
  Real r, g, b, a;
  r = getNewColor(dt, start.getR(), target.getR());
  g = getNewColor(dt, start.getG(), target.getG());
  b = getNewColor(dt, start.getB(), target.getB());
  a = getNewColor(dt, start.getA(), target.getA());

  start = Color(r, g, b, a);
}

void Particle::update(Real dt, Real dampening)
{
  Real colorRatio = dt / m_life;
  
  m_life -= dt;
  

  //cout << "damp: " << dampening << endl;

//  if(isDead())
//  {
//   unregister();
//   return;
//  }

 	m_pos += m_velocity * dt;

  if(dampening < 1.0)
    m_velocity -= (m_velocity * dampening) * dt;
  else
   m_velocity += (m_velocity * dampening) * dt;
  
  changeColors(colorRatio, m_currentCol, m_targetCol);
  m_currentScale = getNewColor(dt, m_currentScale, m_targetScale);
}

void Particle::render(const Vector2<Real>& camPos)
{
  if(m_tex == 0)
    return;
	
	
	glPushMatrix();
    glTranslated(m_pos.x - camPos.x - (m_tex->getPaddedDim().x * m_currentScale) / 2.0,
                 m_pos.y - camPos.y - (m_tex->getPaddedDim().y * m_currentScale) / 2.0, 0.0);
    glScaled(m_currentScale, m_currentScale, 0.0);

		glColor4f(m_currentCol.getR(), m_currentCol.getG(), m_currentCol.getB(), m_currentCol.getA());
		
		glCallList(m_tex->getDisplayListID());
	glPopMatrix();
}

bool Particle::isDead() const
{
  return (m_life <= 0.0);
}
